package com.moli.iov.open.web.exception;

import com.moli.iov.exception.BusinessException;
import com.moli.iov.rest.GenericCode;
import com.moli.iov.rest.RestResponse;
import com.moli.iov.util.StringUtil;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;

/**
 * <p>
 *  全局异常处理
 * </p>
 *
 * @Auther: zql
 * @Date: 2018/12/13 9:46
 */
@Slf4j
@ControllerAdvice
@ResponseBody
public class GlobalExceptionHandle {

    /**
     * 500 - Internal Server Error
     */
    @ResponseStatus(HttpStatus.OK)
    @ExceptionHandler(Exception.class)
    public RestResponse handleException(Exception e) {
        log.error("服务运行异常", e);
        return RestResponse.failure(GenericCode.SYS_BIZ);
    }

    /**
     * 业务异常
     * @return
     */
    @ResponseStatus(HttpStatus.OK)
    @ExceptionHandler(BusinessException.class)
    public RestResponse methodBusinessException(BusinessException e){

        if(StringUtil.isNotBlank(e.getCode())){
            return RestResponse.failure(Integer.parseInt(e.getCode()), e.getMessage());
        }
        log.error("业务异常 异常信息：{}", e.getMessage());
        return RestResponse.failure(e.getMessage());
    }

    /**
     * 500 参数校验失败
     * @param e
     * @return
     */
    @ResponseStatus(HttpStatus.OK)
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public RestResponse methodArgumentNotValidException(MethodArgumentNotValidException e){

        BindingResult bindingResult =  e.getBindingResult();

        String errorMsg = errorMsg(bindingResult);

        log.error("参数校验失败, 失败信息: {}", errorMsg);
        return RestResponse.failure(errorMsg);
    }

    /**
     * 500 参数校验失败
     * @param e
     * @return
     */
    @ResponseStatus(HttpStatus.OK)
    @ExceptionHandler(BindException.class)
    public RestResponse bindHandleException(BindException e){

        BindingResult bindingResult =  e.getBindingResult();

        String errorMsg = errorMsg(bindingResult);

        log.error("参数校验失败, 失败信息: {}", errorMsg);
        return RestResponse.failure(errorMsg);
    }

    /**
     * 参数校验失败提示
     * @param bindingResult
     * @return
     */
    private String errorMsg(BindingResult bindingResult){
        if(bindingResult.hasErrors()) {
            List<ObjectError> ls=bindingResult.getAllErrors();
            if(ls!=null&&ls.size()>0){
                for (int i = 0; i < ls.size(); i++) {
                    String errTemp = ls.get(i).getDefaultMessage();
                    return errTemp;
                }
            }
        }
        return "";
    }

    /**
     * 400 - Bad Request
     */
    @ResponseStatus(HttpStatus.OK)
    @ExceptionHandler(HttpMessageNotReadableException.class)
    public RestResponse handleHttpMessageNotReadableException(HttpMessageNotReadableException e) {
        log.error("参数格式错误", e);
        return RestResponse.failure(GenericCode.JSON_ERROR);
    }

    /**
     * 405 - Method Not Allowed
     */
    @ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED)
    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    public RestResponse handleHttpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException e) {
        log.error("不支持当前请求方法", e);
        return RestResponse.failure("不支持当前请求方法");
    }

    /**
     * 415 - Unsupported Media Type
     */
    @ResponseStatus(HttpStatus.UNSUPPORTED_MEDIA_TYPE)
    @ExceptionHandler(HttpMediaTypeNotSupportedException.class)
    public RestResponse handleHttpMediaTypeNotSupportedException(Exception e) {
        log.error("不支持当前媒体类型", e);
        return RestResponse.failure("不支持当前媒体类型");
    }

}
